﻿/**
*
* @file:    qdatabasepool.h
* @brief:
* @author:  sanshi522@163.com
* @date:    2024-11-03  21:43
*
*
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License along
*  with this program; if not, write to the Free Software Foundation, Inc.,
*  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/

#ifndef QDATABASEPOOL_H
#define QDATABASEPOOL_H

#include <QCoreApplication>
#include <QHash>
#include <QMutex>
#include <QQueue>
#include <QSettings>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QThread>

class QDatabasePool : public QObject
{
    Q_OBJECT

public:
    /**
     * 构造函数
     * @param settings QSettings指针，用于读取配置参数
     * @param parent 父对象
     */
    explicit QDatabasePool(QSettings *settings, QObject *parent = nullptr);
    /**
     * 构造函数
     * @param parent 父对象
     */
    QDatabasePool(QObject *parent = nullptr);

    /**
     * 析构函数
     */
    ~QDatabasePool();

    /**
     * 获取一个数据库连接
     * @return 返回一个有效的数据库连接，如果没有可用连接则返回无效连接
     */
    QSqlDatabase getConnection();

    /**
     * 释放一个数据库连接回连接池
     * @param connection 要释放的数据库连接
     */
    void releaseConnection(QSqlDatabase &connection);

    QString getPoolMark() const;
    void setPoolMark(const QString &value);

    int getMinConnections() const;
    void setMinConnections(int value);

    int getMaxConnections() const;
    void setMaxConnections(int value);

    QString getDatabaseType() const;
    void setDatabaseType(const QString &value);

    QString getDatabaseHost() const;
    void setDatabaseHost(const QString &value);

    int getDatabasePort() const;
    void setDatabasePort(int value);

    QString getDatabaseName() const;
    void setDatabaseName(const QString &value);

    QString getDatabaseUser() const;
    void setDatabaseUser(const QString &value);

    QString getDatabasePassword() const;
    void setDatabasePassword(const QString &value);

    void init();
    void uninit();

private:
    /**
     * 创建数据库文件
     */
    void createDateBase();
    /**
     * 初始化数据库连接
     */
    void initializeConnections();
    /**
     * 反初始化数据库连接
     */
    void deinitializeConnections();

private:
    QString poolMark;         /**< 连接池标识：为避免多个连接池连接同一个数据库时，连接名冲突 */
    int minConnections;       /**< 最小连接数 */
    int maxConnections;       /**< 最大连接数 */
    QString databaseType;     /**< 数据库类型 QSQLITE\QMYSQL... */
    QString databaseHost;     /**< 数据库地址 */
    int databasePort;         /**< 数据库端口 */
    QString databaseName;     /**< 数据库名称 */
    QString databaseUser;     /**< 数据库用户名 */
    QString databasePassword; /**< 数据库密码 */

    QSettings *settings;                       /**< 配置参数 */
    QQueue<QSqlDatabase> idleConnections;      /**< 空闲连接队列 */
    QHash<int, QSqlDatabase> usingConnections; /**< 正在使用的连接哈希表 */
    QMutex mutex;                              /**< 互斥锁，确保线程安全 */
    int nextConnectionId;                      /**< 下一个连接ID */
};

#endif // QDATABASEPOOL_H
